<script setup lang="ts">
import { Slicer } from "@/models/reactiveComponent";
import { computed, ref, watch, inject } from "vue";
import * as injectKeys from "@/services/injectKeys";

const props = defineProps<{ model: Slicer }>();
const model = props.model;

const dbServices = inject(injectKeys.dbKey)!;
const reactdataServices = inject(injectKeys.reactdataServicesKey)!;
const appEventService = inject(injectKeys.appEventServiceKey)!;

appEventService.onResetFilters(() => {
  if (model.multiple) {
    selecteds.value = [];
  } else {
    selecteds.value = null;
  }
});

const filterUtils = reactdataServices.getFilterUtils(model);

const data = filterUtils.getData();

let sqlPropName = null as unknown as string;

const options = computed(() => {
  if (data.value.rows.length > 0) {
    const rows = data.value.rows;

    if (!sqlPropName) {
      sqlPropName = data.value.fields[0];
    }

    return rows.map((r) => {
      // null or undefined
      const noValue = r[sqlPropName] === undefined || r[sqlPropName] === null;

      return {
        label: noValue ? "(空白)" : r[sqlPropName]!.toString(),
        value: r[sqlPropName] ?? null,
      };
    });
  }

  return [];
});

const optionsInitCount = options.value.length;

const selecteds = ref<any[] | any>();

if (model.defaultSelected) {
  if (optionsInitCount > 0) {
    let value = options.value[0].value as any;

    if (model.multiple) {
      value = [value];
    }

    selecteds.value = value;
  }
}

watch(
  selecteds,
  (values) => {
    if (!values) {
      values = [];
    }

    if (!Array.isArray(values)) {
      values = [values];
    }

    values = values.map((v: any) => v.value);

    if (values.length === 0) {
      filterUtils.removeFilter();
    } else {
      const { hasNull, values: valuesWithoutNull } =
        dbServices.extractNullInValues(values);
      const sql = dbServices.valuesArray2sqlArray(valuesWithoutNull).join(",");

      filterUtils.addFilterWithExprFn((field) => {
        const expr = `${field} in (${sql})`;
        if (hasNull) {
          return `${expr} or ${field} is null`;
        }

        return expr;
      });
    }
  },
  { immediate: true }
);

function onRemove(index: number) {
  console.log("onRemove", selecteds.value);

  selecteds.value.splice(index, 1);
}

const overItemsCount = computed(
  () => selecteds.value && selecteds.value.length > 3
);
</script>

<template>
  <div class="slicer-box">
    <q-select
      v-model="selecteds"
      :options="options"
      :label="props.model.title"
      class="cp-select"
      clearable
      dense
      outlined
      use-chips
      v-bind="model.props"
    >
      <!-- <template v-slot:selected>
        <template v-if="overItemsCount">
          <q-chip removable square @remove="onRemove(0)">
            {{ selecteds[0].label }}
          </q-chip>

          <q-chip square> +{{ selecteds.length - 1 }} </q-chip>
        </template>

        <template v-else>
          <q-chip
            v-for="(item, index) in selecteds"
            removable
            square
            @remove="onRemove(index)"
          >
            {{ item.label }}
          </q-chip>
        </template>
      </template> -->
    </q-select>
  </div>
</template>

<style scoped lang="less">
.slicer-box {
  margin-right: 0.8rem;
  min-width: 10rem;
  max-width: 20rem;

  .cp-select {
    width: 100%;
  }
}
</style>
